package com.util;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.log4j.Logger;

import com.db.DbUtil;

public class PartitionMgr {
	private static PartitionMgr inst=null;
	private static Logger log = null;
	private static String baseSql="SELECT TABLE_NAME ,PARTITION_NAME,PARTITION_DESCRIPTION,PARTITION_METHOD,PARTITION_EXPRESSION FROM INFORMATION_SCHEMA.partitions WHERE 1=1 AND  TABLE_SCHEMA = SCHEMA() and partition_method is not null";
	private static Map<String,List<Map<String,Object>>> partitionMap=new ConcurrentHashMap<String,List<Map<String,Object>>>();
	public static PartitionMgr inst(){
		if(inst==null){
			synchronized (baseSql) {
				inst=new PartitionMgr();
			}
		}
		return inst;
	} 
	private PartitionMgr(){}
	static {
		initPartitionMap();
	}
	public static synchronized void initPartitionMap(){
		try {
			List<Map<String,Object>> list=DBUtil.queryForListMap(baseSql);
			partitionMap.clear();
			for(Map<String,Object> map:list){
				String table_name=map.remove("TABLE_NAME").toString();
				if(partitionMap.containsKey(table_name)){
					partitionMap.get(table_name).add(map);
				}else{
					List<Map<String,Object>> tnList=new ArrayList<Map<String,Object>>();
					tnList.add(map);
					partitionMap.put(table_name, tnList);
				}		
			}
			//System.out.println(partitionMap);			
		} catch (Exception e) {
			log.warn(e);
		}	
	}
	public synchronized void addPartition(String []tableName,String field,Map<String,String> partition){
		if(tableName==null || tableName.length==0 || partition==null || partition.isEmpty()) return;		
		for(String table:tableName){
			if(partitionMap.containsKey(table)){
				//获取这个表中的分区数据
				List<Map<String,Object>> partitionMapList = partitionMap.get(table);				
				List<String> PARTITION_DESCRIPTION=new ArrayList<String>();
				for(Map<String,Object> map:partitionMapList){
					//把分区的值域装载到分区描述列表中，因为只有值域是不会重复的，分区名是可以重复的
					PARTITION_DESCRIPTION.add(map.get("PARTITION_DESCRIPTION").toString());
				}
				//对需要增加的分区的map进行遍历，只取该map中的不在分区值域列表的分区，存在的分区则进行移除，最终留下不存在值域列表中的分区
				for(String key:partition.keySet()){
					if(PARTITION_DESCRIPTION.contains(partition.get(key))){
						partition.remove(key);
					}					
				}
				//没有对应的分区名，可以新加分区
				if(partition!=null && !partition.isEmpty()){
					addPartition(table,partitionMapList.get(0).get("PARTITION_METHOD").toString(),partition);
				}
			}
		}
		if(partition!=null && !partition.isEmpty()){
			initPartitionMap();
		}
	}
	private synchronized boolean addPartition(String tableName,String partMethod,Map<String,String> partition){
		if(tableName==null || tableName.equals("") || partition==null || partition.isEmpty()) return false;		
		boolean succ=false;
		String baseSql="alter table "+tableName+" add partition (";
		String partitionDefineStr="";
		if(partMethod.equalsIgnoreCase("list")){
			partitionDefineStr=" in ";
		}else if(partMethod.equalsIgnoreCase("range")){
			partitionDefineStr=" less than ";
		}
		StringBuilder sb=new StringBuilder();
		Iterator<String> it=partition.keySet().iterator();
		while(it!=null && it.hasNext()){
			String key=it.next();
			sb.append(" partition ").append(key).append(" values ").append(partitionDefineStr).append("(").append(partition.get(key)).append("),");
		}
		if(sb.length()>0){
			sb.deleteCharAt(sb.length()-1).append(")").insert(0, baseSql);
		}
		try {
			Connection con=DbUtil.getConnection();
			con.setAutoCommit(false);
			succ=con.createStatement().execute(sb.toString());
			//System.out.println(sb);
		} catch (SQLException e) {
			log.warn((e));
		}
		return succ;
	}
	
	public static void main(String[] args) {
		//inst();
		String tableName[]={"datp0","datp100","datp101","datp102","datp103","datp104","globalindex","activedata",};
		String s="alter table tableName add PARTITION (PARTITION p201101 VALUES IN (201101),PARTITION p201102 VALUES IN (201102),PARTITION p201103 VALUES IN (201103) ,PARTITION p201104 VALUES IN (201104) ,PARTITION p201105 VALUES IN (201105) , PARTITION p201106 VALUES IN (201106) ,PARTITION p201107 VALUES IN (201107) ,PARTITION p201108 VALUES IN (201108) ,PARTITION p201109 VALUES IN (201109) ,PARTITION p201110 VALUES IN (201110) ,PARTITION p201111 VALUES IN (201111) ,PARTITION p201112 VALUES IN (201112) )";
		StringBuilder sb=new StringBuilder();
		for(String table:tableName){
			sb.append(s.replace("tableName", table)).append(";");
		}
		if(sb.length()>0)
			sb.deleteCharAt(sb.length()-1);
		System.out.println(sb);
	}

}
